<?php
/**
 * Description:
 * Author: hezhizheng
 * Date: 2018/11/15
 * Time: 9:57
 * Created by Created by Panxsoft.
 */

namespace App\Services\Customers\Register;

use App\Exceptions\ApiErrCode;
use App\Exceptions\ApiException;
use App\Http\Controllers\Api\V1\App\Customers\ThirdPartyLoginController;
use App\Models\Customers\AlipayUser;
use App\Models\Customers\Customer;
use App\Models\Customers\CustomerGroup;
use App\Models\Customers\WechatUser;
use App\Models\Language;
use App\Models\Store;
use App\Services\MobileApp\AppEnv;
use App\Services\Utils\ApiChecker;
use App\Services\Utils\Transaction;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\JWT;
use Tymon\JWTAuth\JWTGuard;

class EmailRegisterService
{
    use ApiChecker;

    private $customer;

    public function __construct()
    {
        $this->customer = new Customer;
    }

    /**
     * @param Customer $customer
     * @return mixed
     * @throws \Exception
     */
    public function register(Customer $customer)
    {
        $data = $this->assembleData($customer);

        $reg = Transaction::handle(function() use($data){
            $reg = $this->customer->create($data);
            $this->relateSocialiteAccount($reg->customer_id);

            return $reg;
        });

        // 获取登录的jwt_token
        $this->generateJwtToken($reg);

        return $reg;
    }

    /**
     * @param Customer $customer
     * @return array
     */
    private function assembleData(Customer $customer)
    {
        $data = [
            'email'             => $customer->email,
            'password'          => bcrypt($customer->password),
            'language_id'       => AppEnv::languageId(),
            'customer_group_id' => AppEnv::customerGroupId(),
            'store_id'          => Appenv::storeId(),
            'fullname'          => $customer->fullname,
            'image'             => $customer::avatarDefault(),
            'date_added'        => (string) now(),
            'ip'                => $customer->ip,
            'status'            => Customer::STATUS_ENABLE,
        ];

        return $data;
    }

    /**
     * @param $customer_id
     * @return bool
     * @throws ApiException
     * @throws \Exception
     */
    public function relateSocialiteAccount($customer_id)
    {
        $oauth_type = request()->get('oauth_type');
        $oauth_user_id = request()->get('oauth_user_id');

        if (!($oauth_type && $oauth_user_id)) return true;

        switch($oauth_type)
        {
            case ThirdPartyLoginController::THIRD_PARTY_WECHAT_APP:
                $updated = $this->relateWechatByApp($oauth_user_id, $customer_id);
                break;
            case ThirdPartyLoginController::THIRD_PARTY_ALIPAY_APP:
                $updated = (new AlipayUser)->where('alipay_user_id', $oauth_user_id)
                    ->update(['customer_id' => $customer_id]);
                break;
            case ThirdPartyLoginController::THIRD_PARTY_WECHAT_PC:
                $updated = $updated = $this->relateWechatByApp($oauth_user_id, $customer_id);
                break;
            case ThirdPartyLoginController::THIRD_PARTY_ALIPAY_PC:
                $updated = (new AlipayUser)->where('alipay_user_id', $oauth_user_id)
                    ->update(['customer_id' => $customer_id]);
                break;
            default:
                throw new ApiException(ApiErrCode::REQUEST_PARAMS_NOT_IN_RANGE , trans('customer.oauth_type'));
        }

        return $updated;
    }

    /**
     * @param $oauth_user_id
     * @param $customer_id
     * @return bool
     * @throws \App\Exceptions\ApiAbstractException
     */
    private function relateWechatByApp($oauth_user_id, $customer_id)
    {
        $wechat_user = (new WechatUser)->where('wechat_user_id', $oauth_user_id)->first();
            $this->checkIsTrue($wechat_user, trans('customer.wechat_oauth_error'));

        if ($unionid = $wechat_user->unionid ?? null) {

            $updated = (new WechatUser)->where('unionid', $unionid)
                ->update(['customer_id' => $customer_id]);
        } else {
            $updated = (new WechatUser)->update(['customer_id' => $customer_id]);
        }


        return $updated;
    }

    /**
     * @param Customer $customer
     * @return null|string
     */
    public function generateJwtToken(Customer $customer)
    {
        /** @var JWTGuard|JWT $jwt */
        $jwt = Auth::guard(Customer::GUARD_NAME);

        $jwt_token = $jwt->tokenById($customer->customer_id);

        $customer = $customer->refresh();

        return $customer->jwt_token = $jwt_token;
    }
}